package com.example.app.sharescreen;

import android.util.Log;

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.json.JSONException;
import org.json.JSONObject;
import org.webrtc.IceCandidate;
import org.webrtc.SessionDescription;

import java.net.URI;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class WebSocketManager {
    private static final String TAG = "WebSocketManager";
    private WebSocketClient webSocketClient;
    private WebSocketCallback callback;
    private String username;

    public interface WebSocketCallback {
        void onWebSocketOpen();
        void onWebSocketMessage(String type, String fromUser, JSONObject data);
        void onWebSocketClose();
        void onWebSocketError(Exception ex);
    }

    public WebSocketManager(String username, WebSocketCallback callback) {
        this.username = username;
        this.callback = callback;
    }

    public void connect() {
        try {
            // Trust all certificates for development
            TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
                    public void checkClientTrusted(X509Certificate[] certs, String authType) {}
                    public void checkServerTrusted(X509Certificate[] certs, String authType) {}
                }
            };

            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustAllCerts, new SecureRandom());

            String wsUrl = StaticData.RemoteHOSTS + "?username=" + username;
            webSocketClient = new WebSocketClient(new URI(wsUrl)) {
                @Override
                public void onOpen(ServerHandshake handshakedata) {
                    Log.d(TAG, "WebSocket connected");
                    if (callback != null) {
                        callback.onWebSocketOpen();
                    }
                }

                @Override
                public void onMessage(String message) {
                    handleMessage(message);
                }

                @Override
                public void onClose(int code, String reason, boolean remote) {
                    Log.d(TAG, "WebSocket closed");
                    if (callback != null) {
                        callback.onWebSocketClose();
                    }
                }

                @Override
                public void onError(Exception ex) {
                    Log.e(TAG, "WebSocket error: " + ex.getMessage());
                    if (callback != null) {
                        callback.onWebSocketError(ex);
                    }
                }
            };

            webSocketClient.setSocketFactory(sslContext.getSocketFactory());
            javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
                    (hostname, session) -> true);
            webSocketClient.connect();
        } catch (Exception e) {
            Log.e(TAG, "WebSocket initialization error: " + e.getMessage());
            if (callback != null) {
                callback.onWebSocketError(e);
            }
        }
    }

    private void handleMessage(String message) {
        try {
            JSONObject json = new JSONObject(message);
            String type = json.getString("type");
            String fromUser = json.getString("fromUser");
            
            if (callback != null) {
                callback.onWebSocketMessage(type, fromUser, json);
            }
        } catch (JSONException e) {
            Log.e(TAG, "JSON error: " + e.getMessage());
        }
    }

    public void sendCallStart(String toUser) {
        sendJsonMessage("call_start", toUser, null);
    }

    public void sendCallResponse(String toUser, boolean accept) {
        sendJsonMessage("call_back", toUser, accept ? "1" : "0");
    }

    public void sendOffer(String toUser, SessionDescription sessionDescription) {
        sendJsonMessage("offer", toUser, sessionDescription);
    }

    public void sendAnswer(String toUser, SessionDescription sessionDescription) {
        sendJsonMessage("answer", toUser, sessionDescription);
    }

    public void sendIceCandidate(String toUser, IceCandidate iceCandidate) {
        sendJsonMessage("_ice", toUser, iceCandidate);
    }

    public void sendHangup(String toUser) {
        sendJsonMessage("hangup", toUser, null);
    }

    private void sendJsonMessage(String type, String toUser, Object data) {
        try {
            JSONObject message = new JSONObject();
            message.put("type", type);
            message.put("fromUser", username);
            message.put("toUser", toUser);

            if (data != null) {
                if (data instanceof SessionDescription) {
                    SessionDescription sdp = (SessionDescription) data;
                    message.put("sdp", sdp.description);
                    message.put("type", sdp.type.canonicalForm());
                } else if (data instanceof IceCandidate) {
                    IceCandidate candidate = (IceCandidate) data;
                    message.put("sdpMid", candidate.sdpMid != null ? candidate.sdpMid : "");
                    message.put("sdpMLineIndex", candidate.sdpMLineIndex);
                    message.put("candidate", candidate.sdp);
                } else if (data instanceof String) {
                    message.put("msg", data);
                }
            }

            if (webSocketClient != null && webSocketClient.isOpen()) {
                webSocketClient.send(message.toString());
            }
        } catch (JSONException e) {
            Log.e(TAG, "JSON error: " + e.getMessage());
        }
    }

    public void close() {
        if (webSocketClient != null) {
            webSocketClient.close();
            webSocketClient = null;
        }
    }
} 